package com.foreveross.crawl.corn;

import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.calendar.DailyCalendar;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.impl.triggers.SimpleTriggerImpl;

import com.foreveross.crawl.CrawlEngineStartUp;

/**
 *  对于重置时间和缓冲时间的trigger表达式生成工具，待优化
 *  创建任务   00：00 ——23：00  模版到队列
	分发任务   *24                          队列到组管理器
	打包任务   *24                          组管理器到任务记录
	超时扫描   *24                          记录通知
	常规任务   *24                          队列到记录
	补偿任务    00：00 ——23：00 记录回归队列
 * @author guokenye
 *
 */
public class ClearAndResetCornTriggerBuilder {
	private static Logger logger = Logger.getLogger(CrawlEngineStartUp.class);
	private static ClearAndResetCornTriggerBuilder builder;
	private static String timeFormat="^([0-1][0-9]|[2][0-3]):([0][0-9]|[1-5][0-9])$";
	private String cleanTime, resetTime;
	private int cleanTime_hour,cleanTime_minute;
	private int resetTime_hour,resetTime_minute;
	public static final String DEFAULT_WORKER_TRIGGER_NAME="DEFAULT_WORKER_TRIGGER_NAME_";
	public static final String DEFAULT_WORKER_TRIGGER_GROUP_NAME="DEFAULT_WORKER_TRIGGER_GROUP_NAME";
	public static final Integer bufferStep=3;//缓冲步长，单位（minute）
	private ClearAndResetCornTriggerBuilder(){}
	public static ClearAndResetCornTriggerBuilder getInstance(){
		if(builder==null){
			builder=new ClearAndResetCornTriggerBuilder();
		}
		return builder;
	}
	/**
	 * 设置清除时间和重置时间
	 * 如果格式或者逻辑有问题会采用默认的23:00 00:00
	 * @param cleanTime
	 * @param resetTime
	 */
	public void setValue(String cleanTime,String resetTime){
		if(cleanTime==null || !cleanTime.trim().matches(timeFormat) || 
				resetTime==null || !resetTime.trim().matches(timeFormat) || 
				cleanTime.trim().equals(resetTime.trim())){
			this.cleanTime="23:00";
			this.resetTime="00:00";
		}else{
			this.cleanTime=cleanTime.trim();
			this.resetTime=resetTime.trim();
		}
		this.cleanTime_hour=Integer.parseInt(this.cleanTime.replaceAll(":.*", "").replaceAll("^0", ""));
		this.cleanTime_minute=Integer.parseInt(this.cleanTime.replaceAll("[^:]*:", "").replaceAll("^0", ""));
		this.resetTime_hour=Integer.parseInt(this.resetTime.replaceAll(":.*", "").replaceAll("^0", ""));
		this.resetTime_minute=Integer.parseInt(this.resetTime.replaceAll("[^:]*:", "").replaceAll("^0", ""));
		logger.info(String.format("引擎任务清理时间[%s] 重置时间[%s]", this.cleanTime,this.resetTime));
	}
	/**
	 * 运行于24小时的默认组的trigger
	 * @param interval 频率
	 * @return
	 * @throws Exception
	 */
	public SimpleTrigger  buildDefaultGroupTriggerRun24Hours(long interval) throws Exception{
		if(cleanTime==null || resetTime==null){
			throw new Exception("has no setValue!");
		}
		return new SimpleTriggerImpl(DEFAULT_WORKER_TRIGGER_NAME+UUID.randomUUID().toString(), 
				DEFAULT_WORKER_TRIGGER_GROUP_NAME, Integer.MAX_VALUE, interval);
	}
	
	

	
	
	/**
	 * 运行于从重置时间到清理时间的默认组的trigger(当前精度仅仅到分，以后可以继续优化)
	 * @param scheduler 调度器实例
	 * @param interval 频率（毫秒）
	 * @param hasBuffer 是否有缓冲机制（建议开启）(晚开始早结束)
	 * @return
	 * @throws Exception
	 */
	public Trigger  buildDefaultGroupTriggerBetweenResetAndClean(Scheduler scheduler,long interval,boolean hasBuffer) throws Exception{
		if(this.cleanTime==null || this.resetTime==null){
			throw new Exception("has no setValue!");
		}
		DailyCalendar dailyCalendar;
		if(this.cleanTime_hour>this.resetTime_hour){
			dailyCalendar=new DailyCalendar(
					StringUtils.leftPad(this.resetTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.resetTime_minute+"", 2, "0"),
					StringUtils.leftPad(this.cleanTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.cleanTime_minute+"", 2, "0")
					);
			dailyCalendar.setInvertTimeRange(true);
		}else if(this.resetTime_hour>this.cleanTime_hour){
			dailyCalendar=new DailyCalendar(
					StringUtils.leftPad(this.cleanTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.cleanTime_minute+"", 2, "0"),
					StringUtils.leftPad(this.resetTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.resetTime_minute+"", 2, "0")
					);
			dailyCalendar.setInvertTimeRange(false);
		}else if(this.resetTime_minute>this.cleanTime_minute){
			dailyCalendar=new DailyCalendar(
					StringUtils.leftPad(this.cleanTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.cleanTime_minute+"", 2, "0"),
					StringUtils.leftPad(this.resetTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.resetTime_minute+"", 2, "0")
					);
			dailyCalendar.setInvertTimeRange(false);
		}else if(this.cleanTime_minute>this.resetTime_minute){
			dailyCalendar=new DailyCalendar(
					StringUtils.leftPad(this.resetTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.resetTime_minute+"", 2, "0"),
					StringUtils.leftPad(this.cleanTime_hour+"", 2, "0")+":"+StringUtils.leftPad(this.cleanTime_minute+"", 2, "0")
					);
			dailyCalendar.setInvertTimeRange(true);
		}else{
			throw new Exception("无法正确的解析清理和重置时间！");
		}
		String calName=UUID.randomUUID().toString()+System.currentTimeMillis();
		SimpleTriggerImpl trigger=new SimpleTriggerImpl(DEFAULT_WORKER_TRIGGER_NAME+UUID.randomUUID().toString()
				, DEFAULT_WORKER_TRIGGER_GROUP_NAME, new Date(),null, Integer.MAX_VALUE, interval);
		scheduler.addCalendar(calName, dailyCalendar, false, false);
		trigger.setCalendarName(calName);
		return trigger;
	}
	/**
	 * 创建一个启动于重置时间的trigger
	 * @param name
	 * @param groupName
	 * @return
	 * @throws Exception
	 */
	public CronTrigger builderTriggerRunInResetTime(String name,String groupName) throws Exception{
		CronTriggerImpl cronTrigger = new CronTriggerImpl(name+UUID.randomUUID(),groupName); 
		cronTrigger.setCronExpression("0 "+this.resetTime_minute+" "+this.resetTime_hour+"/24 * * ?");
		return cronTrigger;
	}
	
	public static void main(String[] args) throws Exception {
		ClearAndResetCornTriggerBuilder builder =new ClearAndResetCornTriggerBuilder();
		builder.setValue("23:35", "01:00");
		//builder.buildDefaultGroupCornTriggerAfterResetAndBeforeClean(30000);
	}
}
